//
//  ViewBindVMHelper.swift
//  CooperSwift
//
//  Created by 计海峰 on 2022/9/7.
//

import Foundation
import UIKit
import RxSwift
import RxDataSources

// 单独view 绑定 vm <临时使用, 未优化>
public struct ViewBindVMHelper {
    
    /// cv 绑定 vm
    /// 使用：ViewBindVMHelper.bindCVVM(cv, vm, bag: bag)
    /// 刷新：rx.updateRefresh(vm, scrollview: cv, bag: bag, refreshConfig: .all)
    /// - Parameters:
    ///   - cv: UICollectionView
    ///   - vm: RefreshControllable && CollectionViewModelProtocol
    ///   - bag: DisposeBag
    public static func bindCVVM<T: RefreshControllable & CollectionViewModelProtocol >(_ cv: UICollectionView, _ vm: T, bag: DisposeBag) {
        /// 初始化结束
        vm.initDown()
        /// flowout
        if let vm = vm as? CollectionViewBaseVM, let flowLayout = vm.flowLayout {
            cv.collectionViewLayout = flowLayout
        }
        /// collectionview 数据源
        let dataSource: RxCollectionViewSectionedReloadDataSource = vm.configDataSource()
        /// 防抖节流
        vm.sectionsSubject.debounce(.milliseconds(300), scheduler: MainScheduler.instance).bind(to: cv.rx.items(dataSource: dataSource)).disposed(by: bag)
        /// 固定时间刷新节流
//        vm.sectionsSubject.throttle(.milliseconds(300), latest: true, scheduler: MainScheduler.instance).bind(to: cv.rx.items(dataSource: dataSource)).disposed(by: bag)
        /// 绑定key
        vm.bindKey(bag)
        /// delegate 代理
        if let delegate = vm as? UICollectionViewDelegate {
            cv.rx.setDelegate(delegate).disposed(by: bag)
        }
        vm.configServicBlock { service in
            switch service {
            case .collection:
                return cv
            case .controller:
                return nil
            case .view:
               return nil
            case .all:
                return nil
            case .reloadCollection:
                cv.reloadData()
                return nil
            case .endEdit:
                cv.endEditing(true)
                return nil
            }
        }
        /// 配置结束
        vm.configDown()
    }
    
    /// tv 绑定 vm
    /// 使用：ViewBindVMHelper.bindTVVM(cv, vm, bag: bag)
    /// 刷新：rx.updateRefresh(vm, scrollview: cv, bag: bag, refreshConfig: .all)   父对象 实现 Refreshable 协议
    /// - Parameters:
    ///   - cv: UICollectionView
    ///   - vm: RefreshControllable && CollectionViewModelProtocol
    ///   - bag: DisposeBag
    public static func bindTVVM<T: RefreshControllable & TableViewModelProtocol >(_ tv: UITableView, _ vm: T, bag: DisposeBag) {

        /// 初始化结束
        vm.initDown()
        
        /// tableview 数据源
        let dataSource: RxTableViewSectionedReloadDataSource = vm.configDataSource()
        
        /// 防抖节流
        vm.sectionsSubject.debounce(.milliseconds(300), scheduler: MainScheduler.instance).bind(to: tv.rx.items(dataSource: dataSource)).disposed(by: bag)
        
        vm.reloadSubject.filter { _ in
            vm.isRefreshing = true
            return true
        }.debounce(.microseconds(300), scheduler: MainScheduler.instance).subscribe(onNext: { val in
            vm.isRefreshing = false
            tv.reloadData()
        }).disposed(by: bag)
        
        /// 固定时间刷新节流
        /// vm.sectionsSubject.throttle(.milliseconds(300), latest: true, scheduler: MainScheduler.instance).bind(to: tv.rx.items(dataSource: dataSource)).disposed(by: bag)
        
        /// 绑定key
        vm.bindKey(bag)
        /// 部分已写服务
        vm.configServicBlock(bag: bag) { service in
            switch service {
            case .controller:
                return nil
            case .table:
                return tv
            case .view:
                return nil
            case .all:
                return nil
            case .reloadTable:
                vm.reloadTable()
                return nil
            case .endEdit:
                tv.endEditing(true)
                return nil
            }
        }
        /// delegate 代理已实现的话 设置代理
        if let delegate = vm as? UITableViewDelegate {
            tv.rx.setDelegate(delegate).disposed(by: bag)
        }
        /// 执行配置结束 viewmodel的开始方法
        vm.configDown()
    }
    
}
